﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Drawing;
using OpenTK;
using OpenTK.Input;
using Tao.OpenGl;

namespace opentk_first_project
{
    class TestSpriteClass : IGameObject
    {
        Renderer _renderer = new Renderer();
        TextureManager _textureManager;
        Camera _camera;
        Sprite _testSprite = new Sprite();
        Sprite _testSprite2 = new Sprite();
        public TestSpriteClass(TextureManager textureManager, Camera space)
        {
            _textureManager = textureManager;
            _camera = space;
            /*
            _testSprite.Texture = _textureManager.Get("undo");
            _testSprite.SetHeight(256 * 0.1f);
            _testSprite2.Texture = _textureManager.Get("undo");
            _testSprite2.SetPosition(-256, -256);
            _testSprite2.SetColor4(Color4.Red);
             */
        }
        #region IGameObject Members

        public void UpdateInput(Input input)
        {
            
        }
        Vector2 _lastPosition = Vector2.Zero;
        float deltaX = 0;
        float deltaY = 0;
        public void Update(double elapsedTime, Input input)
        {
            Vector2 delta = input.MousePosition - _lastPosition;
            deltaX = (delta.X);
            deltaY = (delta.Y);
            _lastPosition = input.MousePosition;
            //_camera.Zoom(deltaY);
            if (input.KeyState.IsKeyDown(Key.Up))
                _camera.Active(Tranform.MOVE_FORWARD, (float)(100*elapsedTime));
            if (input.KeyState.IsKeyDown(Key.Down))
                _camera.Active(Tranform.MOVE_BACKWARD, (float)(100 * elapsedTime));
            if (input.KeyState.IsKeyDown(Key.Left))
                _camera.Active(Tranform.MOVE_LEFT, (float)(100 * elapsedTime));
            if (input.KeyState.IsKeyDown(Key.Right))
                _camera.Active(Tranform.MOVE_RIGHT, (float)(100 * elapsedTime));
            if (input.KeyState.IsKeyDown(Key.E))
                _camera.Active(Tranform.YAW, 0.5f);
            if (input.KeyState.IsKeyDown(Key.Q))
                _camera.Active(Tranform.YAW, -0.5f);
            if (input.KeyState.IsKeyDown(Key.A))
                _camera.Active(Tranform.PITCH, 1f);
            if (input.KeyState.IsKeyDown(Key.F))
                _camera.Active(Tranform.PITCH, -1f);
            if (input.KeyState.IsKeyDown(Key.Z))
                _camera.Active(Tranform.ROLL, 1f);
            if (input.KeyState.IsKeyDown(Key.C))
                _camera.Active(Tranform.ROLL, -1f);
            if (input.KeyState.IsKeyDown(Key.Space))
                _camera.Active(Tranform.ELEVATE, 1f);
            
        }

        public void Render()
        {
            Color4 cl = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
            GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit);
            GL.PushMatrix();
                drawAxis();
                triangle();
            GL.PopMatrix();

            //drawFloor();

            /*
            for (int i = 0; i < 20; i++)
            {
                
                float[] v1 = new float[3] { vdata[tindices[i, 0], 0], vdata[tindices[i, 0], 1], vdata[tindices[i, 0], 2] };
                float[] v2 = new float[3] { vdata[tindices[i, 1], 0], vdata[tindices[i, 1], 1], vdata[tindices[i, 1], 2] };
                float[] v3 = new float[3] { vdata[tindices[i, 2], 0], vdata[tindices[i, 2], 1], vdata[tindices[i, 2], 2] };
                subdivine(v1,v2,v3,1);
            }
             */
             
            
        }
        private void triangle()
        {
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            GL.Begin(BeginMode.Polygon);
            {
                GL.Color4(Color4.Cyan);
                GL.Vertex3(100, 0, 0);
                GL.Vertex3(0, 0, 0);
                GL.Vertex3(0, 0, 100);
            }
            GL.End();
        }
        private double axisRange = 300;
        void drawFloor()
        {
            GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
            GL.Begin(BeginMode.Polygon);
            {
                GL.Color4(Color4.Red);
                GL.Vertex3(-axisRange, 0.0, 0.0);
                GL.Vertex3(0.0, 0.0, -axisRange);
                GL.Vertex3(axisRange, 0.0, 0.0);
                GL.Color4(0.0f, 1.0f, 0.0f, 1.0f);
                GL.Vertex3(0.0, 0.0, axisRange);
            }
            GL.End();
        }
        void drawAxis()
        {
            GL.Begin(BeginMode.Lines);
            {
                //x axis
                Gl.glColor3d(1.0, 0.0, 0.0);
                Gl.glVertex3d(0.0, 0.0, 0.0);
                GL.Vertex3(axisRange, 0.0, 0.0);
                //y axis
                GL.Color4(0.0f, 1.0f, 0.0f, 1.0f);
                GL.Vertex3(0.0, 0.0, 0.0);
                GL.Vertex3(0.0, axisRange, 0.0);

                GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
                GL.Vertex3(50.0, 00.0, 50.0);
                GL.Vertex3(50.0, axisRange, 50.0);

                //z axis
                GL.Color4(Color4.Blue);
                GL.Vertex3(0.0, 0.0, 0.0);
                GL.Vertex3(0.0 , 0.0, axisRange);
            }
            GL.End();
            GL.Begin(BeginMode.Points);
            {
                //x axis
                GL.Color4(Color4.Cyan);
                GL.Vertex3(axisRange, 0.0, 0.0);
                //y axis
                GL.Color4(Color4.Cyan);
                GL.Vertex3(0.0, axisRange, 0.0);
                //z axis
                GL.Color4(Color4.Cyan);
                GL.Vertex3(0.0, 0.0, axisRange);
            }
            GL.End();

        }
        void drawTriangle(float[] v1, float[] v2, float[] v3)
        {
            GL.Begin(BeginMode.Triangles);                
            GL.Color4(Color4.Red);
            GL.Normal3(v1);
            GL.Vertex3(v1);
            GL.Color4(0.0,1.0,0.0,1.0);
            GL.Normal3(v2);
            GL.Vertex3(v2);
            GL.Color4(Color4.Blue);
            GL.Normal3(v3);
            GL.Vertex3(v3); 
            GL.End();   
                   
        }
        void subdivine(float[] v1, float[] v2, float[] v3, int depth)
        {
            if (depth <= 0)
            {
                drawTriangle(v1, v2, v3);
                return;
            }
           float[] v12 = new float[3];
           float[] v23 = new float[3];
           float[] v31 = new float[3];
           int i;
           for (i = 0; i < 3; i++) 
           { 
              v12[i] = (v1[i]+v2[i]); 
              v23[i] = (v2[i]+v3[i]);     
              v31[i] = (v3[i]+v1[i]); 
           }
           normalize(v12);
           normalize(v23);
           normalize(v31);
           for (i = 0; i < 3; i++)
           {
               v12[i] += (v1[i] + v2[i]) / 2;
               v23[i] += (v2[i] + v3[i]) / 2;
               v31[i] += (v3[i] + v1[i]) / 2;
           }
           drawTriangle(v1, v12, v31);
           drawTriangle(v2, v23, v12);
           drawTriangle(v3, v31, v23);
           drawTriangle(v12, v23, v31);
           subdivine(v1, v12, v31, depth - 1);
           subdivine(v2, v23, v12, depth - 1);
           subdivine(v3, v31, v23, depth - 1);
           subdivine(v12, v23, v31, depth - 1);
        }
        void normalize(float[] v) 
        {    
            double dp = v[0]* v[0] + v[1] * v[1] + v[2] * v[2];
            float d = (float)Math.Sqrt(dp);
            if (d == 0.0) { 
                return;
            }
            v[0] /= d;
            v[1] /= d;
            v[2] /= d;
        }
        void normcrossprod(Vector3 v1, Vector3 v2, float[] v3) 
        { 
           v3[0] = v1.Y * v2.Z - v1.Z * v2.Y;
           v3[1] = v1.Z * v2.X - v1.X * v2.Z;
           v3[2] = v1.X * v2.Y - v1.Y * v2.Z; 
           normalize(v3); 
        }

        #endregion

        #region Khoi 20 mat
        const float X = 52.5731112119133606f ;
        const float Z = 85.0650808352039932f;
        float[,] vdata = new float[12,3]{    
           {-X, 0.0f, Z}, {X, 0.0f, Z}, {-X, 0.0f, -Z}, {X, 0.0f, -Z},    
           {0.0f, Z, X}, {0.0f, Z, -X}, {0.0f, -Z, X}, {0.0f, -Z, -X},    
           {Z, X, 0.0f}, {-Z, X, 0.0f}, {Z, -X, 0.0f}, {-Z, -X, 0.0f}};
        int[,] tindices= new int[20,3]{ 
           {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
           {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
           {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
           {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
        #endregion
    }
}

